using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Xml;
using System.ServiceModel.Security;

namespace SecurityTokenServiceNS
{
    internal class EncryptedData
    {
		private string _encryptingAlgorithm;
		private SymmetricAlgorithm _symmetricAlgorithm;
        private SecurityKeyIdentifier _keyIdentifier;
        private SecurityTokenSerializer _tokenSerializer;
		private byte[] _iv;
		private byte[] _cipherText;

		internal EncryptedData(SecurityKeyIdentifier keyIdentifier, string encryptingAlgorithm,
			SymmetricAlgorithm symmetricAlgorithm, byte[] buffer, long length)
        {
			_tokenSerializer = new WSSecurityTokenSerializer(true);
			_keyIdentifier = keyIdentifier;
			_encryptingAlgorithm = encryptingAlgorithm;
			_symmetricAlgorithm = symmetricAlgorithm;
			Encrypt(buffer, length);
        }

		private void Encrypt(byte[] buffer, long length)
		{
			RandomNumberGenerator generator = new RNGCryptoServiceProvider();
			_iv = new byte[_symmetricAlgorithm.BlockSize / 8];
			generator.GetBytes(_iv);
			//_symmetricAlgorithm.Padding = PaddingMode.PKCS7;
			_symmetricAlgorithm.Padding = PaddingMode.ISO10126;
			_symmetricAlgorithm.Mode = CipherMode.CBC;
			using (ICryptoTransform transform = _symmetricAlgorithm.CreateEncryptor(_symmetricAlgorithm.Key, _iv))
			{
				_cipherText = transform.TransformFinalBlock(buffer, 0, Convert.ToInt32(length));
			}
		}

		public void WriteTo(XmlWriter writer)
		{
			writer.WriteStartElement("enc", Constants.XMLEncryption.Elements.EncryptedData, Constants.XMLEncryption.NamespaceUri);
			writer.WriteAttributeString("Type", null, Constants.XMLEncryption.Type);

			writer.WriteStartElement("enc", Constants.XMLEncryption.Elements.EncryptionMethod, Constants.XMLEncryption.NamespaceUri);
			writer.WriteAttributeString("Algorithm", null, _encryptingAlgorithm);
			writer.WriteEndElement();

			_tokenSerializer.WriteKeyIdentifier(XmlDictionaryWriter.CreateDictionaryWriter(writer), _keyIdentifier);

			writer.WriteStartElement("enc", Constants.XMLEncryption.Elements.CipherData, Constants.XMLEncryption.NamespaceUri);
			writer.WriteStartElement("enc", Constants.XMLEncryption.Elements.CipherValue, Constants.XMLEncryption.NamespaceUri);
			writer.WriteBase64(_iv, 0, _iv.Length);
			writer.WriteBase64(_cipherText, 0, _cipherText.Length);
			writer.WriteEndElement();	//</enc:CipherValue>
			writer.WriteEndElement();	//</enc:CipherData>
			writer.WriteEndElement();	//</enc:EncryptedData>
        }
    }

 

}
